/////////////////////////////////////////////////////////////////////////////////////////////
// Filename: ApplicationiLayer.cpp
// (c) Dave Ottley, 2012. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////
//		MY INCLUDES
///////////////////////////
#include "ApplicationLayer.h"
#include "AppOwnedStates.h"
#include "StateMachine.h"
#include "Util.h"
#include "Constants.h"
#include "D3DClass.h"
#include "WindowsClass.h"
#include "InputClass.h"
#include "GameTimer.h"
#include "Messages.h"
#include "SubsystemID.h"


/////////////////////////////////////////////////////////////////////////////////////////////
// 
//						CONSTRUCTOR / GET INSTANCE
//
//			Initialize and setup application state machine.
/////////////////////////////////////////////////////////////////////////////////////////////
ApplicationLayer::ApplicationLayer() : 
	mAppPaused(false), 
	mID(SubsystemID::APPLICATION),
	mPlayers(NUM_PLAYERS)
{

	mOS = WindowsCls;
	mInput = InputCls;
	mGraphics = D3DCls;
	mTimer = GTimer;
	
	mStateMachine = new StateMachine<ApplicationLayer>(this);

	mStateMachine->SetCurrentState( MainMenuPlayState::GetInstance() );
	mStateMachine->SetGlobalState( ApplicationGlobalState::GetInstance() );

}

ApplicationLayer* ApplicationLayer::GetInstance()
{
	static ApplicationLayer theOne;

	return &theOne;
}

/////////////////////////////////////////////////////////////////////////////////////////////
// 
//						DESTRUCTOR / SHUTDOWN
//
/////////////////////////////////////////////////////////////////////////////////////////////
ApplicationLayer::~ApplicationLayer()
{
	mInput->Shutdown();
	mGraphics->Shutdown();
	mOS->Shutdown();

	delete mStateMachine;

}


/////////////////////////////////////////////////////////////////////////////////////////////
// 
//						INITIALIZE
//
/////////////////////////////////////////////////////////////////////////////////////////////
bool ApplicationLayer::Initialize(HINSTANCE hInstance, int nCmdShow)
{
	if(!mOS->Initialize(hInstance, nCmdShow))
		return false;
	if(!mInput->Initialize() )
		return false;
	if(!mGraphics->Initialize() )
		return false;
	
	return true;
}

/////////////////////////////////////////////////////////////////////////////////////////////
// 
//						RUN
//
/////////////////////////////////////////////////////////////////////////////////////////////
int ApplicationLayer::Run()
{
	static MSG msg = {};
	//Main loop
	while(msg.message != WM_QUIT)
	{
		if(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE) )
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			GTimer->Tick();

			mInput->ReleaseBatchInput();	// Gets batch input if enough time has passed
		
			InitScene();			// Clears scene to PINK

			UpdateScene();			// Updates all members of entity list

 			PresentScene();			// Presents backbuffer to screen
					
		}
			
	}

	return (int)msg.wParam;
}


